/*
 * Copyright © OpenAtom Foundation.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *     http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package io.iec.edp.caf.generator.compileunit;

import java.util.ArrayList;

import io.iec.edp.caf.generator.BaseGenerator;
import io.iec.edp.caf.generator.BaseGeneratorContext;
import io.iec.edp.caf.generator.baseInfo.CompilationUnitInfo;

/**
 * @author liu_wei
 */
public abstract class CompileUnitGenerator extends BaseGenerator {

    protected CompileUnitGeneratorContext getContext() {
        return (CompileUnitGeneratorContext) super.getContext();
    }

    // region Init
    @Override
    protected final BaseGeneratorContext createContext() {
        CompileUnitGeneratorContext context = createProjectInfoContext();
        CompilationUnitInfo assemblyInfo = new CompilationUnitInfo();
        assemblyInfo.setAst(ast);
        context.setCompilationUnitInfo(assemblyInfo);
        return context;
    }

    protected abstract CompileUnitGeneratorContext createProjectInfoContext();

    // endregion

    // region DoGenerate
    @Override
    protected final void doGenerate() {
        buildProjectBasicInfo();

        getContext().getCompilationUnitInfo().generate();
//		Context.GeneratedAssembly = Context.ProjectAssemblyInfo.BuildAssembly();
    }

    private void buildProjectBasicInfo() {
//				String assemblyName = GetAssemblyName();
//				String nameSpace = GetDefaultNamespace();
////				String targetFrame = GetTargetFrame();
////				OutputType outputType = GetOutputType();
//				getContext().SetAssemblyInfo(assemblyName, nameSpace, AddReferences(), targetFrame, outputType);
//				getContext().ProjectAssemblyInfo.RequestAssemblyRaw = RequestAssemblyRaw;
//
//				var rawRefs = AddRawReferences();
//				if(rawRefs != null)
//				{
//	//C# TO JAVA CONVERTER TODO TASK: Lambda expressions and anonymous methods are not converted by C# to Java Converter:
//					rawRefs.ForEach(raw => Context.ProjectAssemblyInfo.AddRefAssemblies(raw));
//				}
//				Context.ProjectAssemblyInfo.GenerateType = GetGenerateType();
//				if (Context.ProjectAssemblyInfo.GenerateType == GenerateType.LocalFile || Context.ProjectAssemblyInfo.GenerateType == GenerateType.Both)
//				{
//					Context.ProjectAssemblyInfo.FilePath = GetFilePath();
//				}
        ArrayList<String> imports = addImports();
        if (imports != null) {
            imports.forEach(i -> getContext().addImport(i));
        }

        String packageName = getPackageName();
        if (packageName == null || "".equals(packageName)) {
            throw new RuntimeException("生成器[" + this.getClass().getName() + "]没有设置包名");
        }
        getContext().setPackageName(packageName);
        getContext().setFilePath(getFilePath());
    }

    // endregion

    // region ���෽��

//	protected GenerateType GetGenerateType() {
//		return GenerateType.Memory;
//	}

    protected String getFilePath() {
        return "";
    }

    protected abstract String getPackageName();
//	protected String GetServerPath() {
//		return GspEnvironment.RootPath;
//	}

//	protected abstract String GetAssemblyName();
//
//	protected abstract String GetDefaultNamespace();

//	protected String GetTargetFrame() {
//		return ".NET CORE 2.0";
//	}
//
//	protected OutputType GetOutputType() {
//		return OutputType.DynamicallyLinkedLibrary;
//	}

    protected ArrayList<String> addImports() {
        return new ArrayList<String>();
    }

    @Override
    protected final void addImport(String importName) {
        getContext().addImport(importName);
    }

//	protected java.util.ArrayList<Assembly> AddReferences() {
//		return null;
//	}

//	protected java.util.ArrayList<Byte[]> AddRawReferences() => null;
//
//	protected boolean RequestAssemblyRaw => false;

    // endregion
//
//	public final void SetRefProjectGen(ProjectInfoGenerator refGen) {
//		Context.SetIsRef(true);
//		Context.SetRefProjectGen(refGen.Context);
//	}

    public final void addChildGenerator(BaseGenerator childGen) {
        addChildGenerators(childGen);
    }

}
